﻿package igz.fleaxy.util
{
	import igz.fleaxy.debug.Console;
	import igz.fleaxy.locale.LocaleManager;
	/**
	 * ...
	 * @author Intelygenz [www.intelygenz.com]
	 */
	public class DateTimeUtil {

		public function DateTimeUtil() {
			
		}
		
		static public function $IsDateTimeType(p_type:String) : Boolean {
			return DateTimeTypes.TYPES.indexOf(p_type) == -1 ? false : true;
		}

		static public function $Clone(p_date:Date) : Date {
			return new Date (p_date.getFullYear()
							,p_date.getMonth()
							,p_date.getDate()
							,p_date.getHours()
							,p_date.getMinutes()
							,p_date.getSeconds()
							,p_date.getMilliseconds()
							);
		}

		static public function $ParseToDateTimeType(p_dataTimeFormat:String) : String {
			var regExp:RegExp;
			var dataTimeFormat:String = p_dataTimeFormat;

			regExp = new RegExp("YYYY|YYY|YY", "g");
			dataTimeFormat = dataTimeFormat.replace(regExp, DateTimeTypes.YEAR);

			regExp = new RegExp("MMM|MM", "g");
			dataTimeFormat = dataTimeFormat.replace(regExp, DateTimeTypes.MONTH);

			regExp = new RegExp("DDD|DD", "g");
			dataTimeFormat = dataTimeFormat.replace(regExp, DateTimeTypes.DAY);

			regExp = new RegExp("hhh|h24|hh", "g");
			dataTimeFormat = dataTimeFormat.replace(regExp, DateTimeTypes.HOUR);

			regExp = new RegExp("mmm|mm", "g");
			dataTimeFormat = dataTimeFormat.replace(regExp, DateTimeTypes.MINUTE);

			regExp = new RegExp("sss|ss", "g");
			dataTimeFormat = dataTimeFormat.replace(regExp, DateTimeTypes.SECOND);

			return dataTimeFormat;
		}

		static public function $ToDate(p_date:String, p_formatIn:String = null ) : Date {
			var formatIn:String = p_formatIn == null ? DateTimeFormat.DEFAULT_DATE : p_formatIn;
			formatIn = DateTimeUtil.$ParseToDateTimeType( formatIn );
			var date:Date = new Date(2000,1,1,0,0,0,0);
			var dateS:String = p_date;
			
			if (   p_formatIn == DateTimeFormat.NUMBER_DATE
				|| p_formatIn == DateTimeFormat.NUMBER_TIME
				|| p_formatIn == DateTimeFormat.NUMBER_DATETIME ) {

				var dateTimeFormatType:String;
				var idxLen:int;
				var idx:int;
				var value:String;
				for ( var f:int = 0, F:int = DateTimeTypes.TYPES.length; f < F; f++ ) {
					dateTimeFormatType = DateTimeTypes.TYPES[f];
					idxLen = dateTimeFormatType.length;
					idx    = formatIn.indexOf( dateTimeFormatType );
					if ( idx != -1 ) {
						value  = dateS.substr(idx, idxLen);
						date = DateTimeUtil.$SetValue ( date, parseInt(value), dateTimeFormatType );
					}
				}
			}
			else {
				var dateTerm:String, timeTerm:String;
				var indexTime:Number;
				
				var formatDateIn : String = formatIn;
				indexTime = formatIn.search(/\w+:/);
				if ( indexTime != -1 ) {
					formatDateIn = StringUtil.$Trim(formatIn.substring(0, indexTime), StringTrimType.TRIM_ALL);
				}
				
				indexTime = dateS.search(/\d+:/);
				if ( indexTime == -1 ) {
					dateTerm = dateS;
				}
				else {
					dateTerm = dateS.substring(0, indexTime);
					timeTerm = dateS.substr(indexTime);
				}
				_ToDate(date, dateTerm.split(/[-\/\.]/), formatDateIn.split(/[-\/\.]/) ); // - / . are date delimiters
				if ( timeTerm != null) {
					_ToDate(date, timeTerm.split(":"), formatIn.substr(formatIn.search(/\w+:/)).split(":"));
				}
			}
			
			return date;
		}
		
		/**
		 * Put the date value (p_dateValue) into p_date considering the format (p_dateFormat)
		 */
		static private function _ToDate(p_date:Date, p_dateValue:Array, p_dateFormat:Array):void {
			
			if (p_dateValue.length==1 && p_dateValue[0] =="") {
				p_date = null;				
			}
			else if ( p_dateValue.length == p_dateFormat.length ) {
				var i:Number;
				for (i = 0; i < p_dateValue.length; i++) {
					DateTimeUtil.$SetValue(p_date, parseInt(p_dateValue[i]), p_dateFormat[i]);
				}
			}
			else {
				throw new Error("DateTimeUtil._ToDate  p_dateValue.length["+p_dateValue+"] p_dateFormat.length["+p_dateFormat+"] are different ")
			}
		}

		/*static private function TodayYesterday( p_date:Date ) : String {
			var date:Date = p_date;
			var dateNow:Date = new Date();
			var todayYesterday:String = "";

			if ( date.toLocaleDateString() == dateNow.toLocaleDateString() ){
				todayYesterday = LocaleManager.GetText("DATETIME", "TODAY");
			}

			var oneDay:int = (1000 * 60 * 60 * 24); 
			var dateNowMinusOneDay:Date = new Date( dateNow.getTime() - oneDay );
			if ( date.toLocaleDateString() == dateNowMinusOneDay.toLocaleDateString() ){
				todayYesterday = LocaleManager.GetText("DATETIME", "YESTERDAY");
			}

			var twoDays:int = oneDay * 2;
			var dateNowMinusTwoDays:Date = new Date( dateNow.getTime() - twoDays );
			if ( date.toLocaleDateString() == dateNowMinusTwoDays.toLocaleDateString() ){
				todayYesterday = LocaleManager.GetText("DATETIME", "TWODAYSAGO");
			}

			return todayYesterday;
		}*/

		static public function $ToString(p_date:Date, p_formatOut:String = null, p_todayYesterday : Boolean = false ) : String {
			var dateS:String  = "";
			if ( p_date!=null ) {
				var date:Date = p_date;
				var formatOut:String = p_formatOut == null ? DateTimeFormat.DEFAULT_DATE : p_formatOut;
				
				/*if ( p_todayYesterday ){
					var p_todayYesterdayDate : String =  TodayYesterday(date);
					if ( p_todayYesterdayDate != "" ){
						return p_todayYesterdayDate;
					}
				}*/

				dateS = formatOut;
				var valueS:String = "";

				var dateTimeFormatType:String;
				
				var f:uint, F:uint = DateTimeTypes.TYPES.length;
				for ( f = 0; f < F; f++ ) {
					dateTimeFormatType = DateTimeTypes.TYPES[f];
					valueS = DateTimeUtil.$GetValue ( p_date, dateTimeFormatType );
					if ( valueS != "" ) {
						dateS = dateS.replace(new RegExp(dateTimeFormatType, "g"), valueS);
						//dateS = StringUtil.$Replace(dateS, dateTimeFormatType, valueS );	
					}
				}
			}
			return dateS;
		}

		static public function $GetValue ( p_date:Date, p_dateTimeType:String ) : String {
			var valueS:String = "";

			switch ( p_dateTimeType ) {
				case DateTimeTypes.YEAR :
					valueS = p_date.getFullYear().toString();
					break;

				case DateTimeTypes.MONTH_NAME :
					//valueS = DateNames.$GetMonthName( p_date.getMonth());
					valueS = _GetMonthName( p_date.getMonth() );					
					break;
				/*case DateTimeTypes.SHORT_MONTH_NAME :
					valueS = DateNames.$GetMonthName( p_date.getMonth()).substr(0,3);
					break;*/
				case DateTimeTypes.FULL_MONTH :
					valueS = (p_date.getMonth()+1).toString();
					if ( parseInt(valueS) < 10 ) {
						valueS = "0" + valueS;
					}
					break;
				case DateTimeTypes.MONTH :
					valueS = (p_date.getMonth()+1).toString();
					break;
				case DateTimeTypes.FULL_DAY :
					valueS = p_date.getDate().toString();
					if ( parseInt(valueS) < 10 ) {
						valueS = "0" + valueS;
					}
					break;
				case DateTimeTypes.WEEK_DAY :
					//valueS = DateNames.$GetWeekName( p_date.getDay() );
					valueS = _GetWeekName( p_date.getDay() );	
					break;
				case DateTimeTypes.WEEK_DAY_SHORT :
					//valueS = DateNames.$GetWeekShortName( p_date.getDay() );
					valueS = _GetWeekShortName( p_date.getDay() );	
					break;
				case DateTimeTypes.DAY :
					valueS = p_date.getDate().toString();
					break;

				case DateTimeTypes.FULL_HOUR :
					valueS = "0"+p_date.getHours().toString();
					if ( valueS.length > 2 ) {
						valueS = valueS.substring(1, 3);
					}
					break;
				case DateTimeTypes.HOUR_12 :
					valueS = p_date.getHours().toString();
					if ( parseInt(valueS) > 12 ) {
						valueS = (parseInt(valueS)-12)+"pm";
					}
					else {
						valueS = valueS+"am";
					}
					break;
				case DateTimeTypes.HOUR_24 :
					valueS = p_date.getHours().toString();
					break;
				case DateTimeTypes.HOUR :
					valueS = p_date.getHours().toString();
					break;

				case DateTimeTypes.FULL_MINUTE :
					valueS = p_date.getMinutes().toString();
					if ( parseInt(valueS) < 10 ) {
						valueS = "0" + valueS;
					}
					break;
				case DateTimeTypes.MINUTE :
					valueS = p_date.getMinutes().toString();
					break;

				case DateTimeTypes.FULL_SECOND :
					valueS = p_date.getSeconds().toString();
					if ( parseInt(valueS) < 10 ) {
						valueS = "0" + valueS;
					}
					break;
				case DateTimeTypes.SECOND :
					valueS = p_date.getSeconds().toString();
					break;

				case DateTimeTypes.MILLISECOND :
					valueS = p_date.getMilliseconds().toString();
					break;
			}

			return valueS;
		}
		
		//private function _GetValue_FillZero () : void {
			//
		//}
		
		static public function $SetValue ( p_date:Date, p_value:int, p_dateTimeType:String ) : Date {

			var date:Date = p_date;			
			switch ( p_dateTimeType ) {
				case DateTimeTypes.YEAR :
					date.setFullYear(p_value);
					break;

				case DateTimeTypes.MONTH_NAME :
				
					break;
				case DateTimeTypes.FULL_MONTH :
				case DateTimeTypes.MONTH :
					var mes:int = p_value - 1;
					date.setMonth( mes );
					break;

				case DateTimeTypes.WEEK_DAY_SHORT :

					break;
				case DateTimeTypes.WEEK_DAY :

					break;
				case DateTimeTypes.FULL_DAY :
				case DateTimeTypes.DAY :
				date.setDate(p_value);
					break;

				case DateTimeTypes.HOUR_12 :

					break;
				case DateTimeTypes.HOUR_24 :
				case DateTimeTypes.HOUR :
					date.setHours( p_value );
					break;

				case DateTimeTypes.FULL_MINUTE :
				case DateTimeTypes.MINUTE :
					date.setMinutes( p_value );
					break;

				case DateTimeTypes.FULL_SECOND :
				case DateTimeTypes.SECOND :
					date.setSeconds(p_value);
					break;

				case DateTimeTypes.MILLISECOND :
					date.setMilliseconds(p_value);
					break;
			}

			return date;
		}

		/**
		 * Compara 2 fechas, permite especificar el grado de comparación a nivel de día, mes, año
		 * @param	p_dateTimeA : Fecha a comparar
		 * @param	p_dateTimeB : Fecha a comparar
		 * @param	p_dateTimeType : Misma fecha a nivel de DateTimeTypes.DAY, DateTimeTypes.MONTH, DateTimeTypes.YEAR
		 * 							 Si se deja como null compara la fechas exactas incluidos los milisegundos
		 * @return
		 */
		static public function $Compare(p_dateTimeA:Date, p_dateTimeB:Date, p_dateTimeType:String = null) : Boolean {
			var equals:Boolean = true;
			if ( p_dateTimeType == null ) {
				equals = (p_dateTimeA.getTime() == p_dateTimeB.getTime());
			}
			switch ( p_dateTimeType ) {
				case DateTimeTypes.DAY :
					equals = p_dateTimeA.getDate() == p_dateTimeB.getDate();
				case DateTimeTypes.MONTH :
					equals = p_dateTimeA.getMonth() == p_dateTimeB.getMonth() && equals;
				case DateTimeTypes.YEAR :
					equals = p_dateTimeA.getFullYear() == p_dateTimeB.getFullYear() && equals;
			}
			return equals;
		}
		
		
		static private function _GetMonthName( p_month : Number ) : String {
			var monthName:Array = LocaleManager.$GetText("DATETIME", "MONTHNAMES").split(",");
			return monthName[p_month];
		}
		
		static private function _GetWeekName( p_weekDay : Number ) : String {
			var weekName:Array = LocaleManager.$GetText("DATETIME", "WEEKNAMES").split(",");
			p_weekDay--;
			if ( p_weekDay < 0 ) {
				p_weekDay = weekName.length - 1;
			}
			return weekName[p_weekDay];
		}

		static private function _GetWeekShortName( p_weekDay : Number ) : String {		
			var weekName:Array = LocaleManager.$GetText("DATETIME", "WEEKNAMES_SHORT").split(",");
			p_weekDay = p_weekDay == 0 ? 7 : p_weekDay;
			p_weekDay--;
			return weekName[p_weekDay];
		}
		
		/**
		 * Devuelve el número de días de un determinado mes según el año
		 * @param	p_year
		 * @param	p_month
		 * @return
		 */
		static public function $GetMonthDays ( p_year:uint, p_month:uint ) : uint {
			var date:Date = new Date(p_year, p_month, 0);
			return date.getDate();
		}
		
		/**
		 * Devuelve como boolean si una determinada fecha es valida
		 * @param	p_date
		 * @param	p_formatDate
		 * @return
		 */
		static public function $Validate ( p_date:String, p_formatDate:String = "DD/MM/YYYY") : Boolean {//DateTimeFormat.DEFAULT_DATE) : Boolean {
			var valid : Boolean = false;
			var date:Array;
			if ( p_formatDate == DateTimeFormat.DEFAULT_DATE && StringUtil.$Validate(p_date,RegExpType.$DATE) ) {
				date = p_date.split("/");
				var dateTemp : Date = DateTimeUtil.$ToDate(p_date, p_formatDate);
				valid = date[1] == dateTemp.getMonth() + 1;
				valid = date[0] == dateTemp.getDate();
			}
			
			return valid;
		}
	}
	
}